/*	$Id: dlink.h 7 2008-07-29 02:58:11Z phrakt $	*/
/*
 * Copyright (c) 2003 Jean-Francois Brousseau <jfb@openbsd.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#ifndef _PFORGE_DLINK_H_
#define _PFORGE_DLINK_H_

#include <sys/types.h>
#include <sys/time.h>

#include <pforge/dltypes.h>

#define PFDL_DEV_MAXNAMELEN 32


/* datalink interface types */
#define PFDL_TYPE_INVAL  0  /* invalid */
#define PFDL_TYPE_BPF    1  /* Berkeley Packet Filter */
#define PFDL_TYPE_DLPI   2  /* DataLink Provider Interface */
#define PFDL_TYPE_LPKT   3  /* Linux packet(7) interface */
#define PFDL_TYPE_PCAP   4  /* libpcap dump file compatibility */
#define PFDL_TYPE_FILE   5  /* packet forge dump file format */
#define PFDL_TYPE_ANY  255  /* wildcard for best pick */


/* ctl request types */
#define PFDL_CTL_SPROMISC   1    /* set (or unset) promiscuous mode */
#define PFDL_CTL_GPROMISC   2    /* get promiscuous mode */
#define PFDL_CTL_SRTIMEOUT  3    /* set read timeout */
#define PFDL_CTL_GRTIMEOUT  4    /* get read timeout */
#define PFDL_CTL_GSTATS     5    /* get statistics */

/* the following control types are specific to dlink_pcap */
#define PFDL_CTL_SINFILE    6
#define PFDL_CTL_GINFILE    7
#define PFDL_CTL_SOUTFILE   8
#define PFDL_CTL_GOUTFILE   9

#define PFDL_CTL_SFLTR     10	/* set an input filter */
#define PFDL_CTL_GFLTR     11	/* get input filters */
#define PFDL_CTL_FFLTR     12	/* flush all filters previously set */

/* dlink flags */
#define PFDL_NONBLOCK    0x0001		/* use non-blocking I/O */
#define PFDL_BOUND       0x0002		/* bound to an interface */


/* PCAP support */
#define PFPCAP_EOS    ((PF_PKT *)-1L)

#define PFPCAP_READ        0x0001
#define PFPCAP_WRITE       0x0002
#define PFPCAP_APPEND      0x0004
#define PFPCAP_BOSWAP      0x0008

typedef struct pf_pcap_file PF_PCAP;


struct pf_dlink_stats {
	u_long    dl_inbytes;
	u_long    dl_outbytes;
	u_long    dl_inpkt;	/* number of input packets */
	u_long    dl_outpkt;	/* number of output packets */
	u_long    dl_fltpkt;	/* filtered packets */
};


typedef struct pf_dlink {
	char            dldev[PFDL_DEV_MAXNAMELEN];
	int           dltype;
	int           dlflags;
	int             dlfd;		/* datalink descriptor */
	struct timeval  timeout;
	int           dl_ref;		/* reference count */

	/* read buffer */
	void   *rbuf;
	size_t  rbufsz;

	/* interface-specific data */
	void   *dldata;

	struct pf_dlink_stats dl_stats;
} PF_DLINK;


struct pf_dlink_ops {
	int      (*dlk_open)  (PF_DLINK *);
	int      (*dlk_close) (PF_DLINK *);
	int      (*dlk_bind)  (PF_DLINK *, int);
	int      (*dlk_ctl)   (PF_DLINK *, int, void *);
	PF_PKT*  (*dlk_read)  (PF_DLINK *);
	ssize_t  (*dlk_write) (PF_DLINK *, void *, size_t);
};



int       pf_dlink_init     (void);
PF_DLINK* pf_dlink_open     (int);
int       pf_dlink_close    (PF_DLINK *);
int       pf_dlink_bind     (PF_DLINK *, int);
int       pf_dlink_ctl      (PF_DLINK *, int, void *);
PF_PKT*   pf_dlink_read     (PF_DLINK *);
ssize_t   pf_dlink_write    (PF_DLINK *, void *, size_t);
PF_PKT*   pf_dlink_readpkt  (PF_DLINK *);
int       pf_dlink_writepkt (PF_DLINK *, PF_PKT *);

int       pf_dlink_getbyname (const char *, int *);

/* interface to pcap-format files */
PF_PCAP*  pf_pcap_open      (const char *, int);
int       pf_pcap_close     (PF_PCAP *);
PF_PKT*   pf_pcap_readpkt   (PF_PCAP *);
int       pf_pcap_writepkt  (PF_PCAP *, PF_PKT *);
int       pf_pcap_getsnaplen(PF_PCAP *);
int       pf_pcap_setsnaplen(PF_PCAP *, int);
int       pf_pcap_getdlt    (PF_PCAP *);
int       pf_pcap_setdlt    (PF_PCAP *, int);
int       pf_pcap_dlt2pf    (int);

#endif	/* _PFORGE_DLINK_H_ */
